<?php
function cfg() {
    static $c = null;
    if ($c === null) $c = require __DIR__ . '/config.php';
    return $c;
}

function db() {
    static $pdo = null;
    if ($pdo === null) {
        $c = cfg();
        $pdo = new PDO($c['db_dsn'], $c['db_user'], $c['db_pass'], [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
        ]);
    }
    return $pdo;
}

function client_ip(): string {
    // 为避免伪造，不信任 X-Forwarded-For（如需反代，请在受控环境自行白名单）
    return $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
}

function anonymize_ip(string $ip): string {
    if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
        $parts = explode('.', $ip);
        $parts[3] = '0';
        return implode('.', $parts);
    }
    if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
        // 将后 8 字节清零（粗粒度匿名）
        $bin = inet_pton($ip);
        if ($bin === false) return '::';
        $bytes = str_split($bin);
        for ($i = 8; $i < 16; $i++) $bytes[$i] = "\x00";
        return inet_ntop(implode('', $bytes));
    }
    return '0.0.0.0';
}

function hash_str(string $s): string {
    $salt = cfg()['hash_salt'];
    return hash('sha256', $salt . '|' . $s);
}

function require_admin() {
    $u = cfg()['admin_user']; $p = cfg()['admin_pass'];
    if (!isset($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'])
        || $_SERVER['PHP_AUTH_USER'] !== $u
        || $_SERVER['PHP_AUTH_PW']   !== $p) {
        header('WWW-Authenticate: Basic realm="VisitorLog Admin"');
        header('HTTP/1.0 401 Unauthorized');
        echo 'Auth required';
        exit;
    }
}
